package com.huiminpay.paymentagent.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.paymentagent.api.PayChannelAgentService;
import com.huiminpay.paymentagent.api.conf.AliConfigParam;
import com.huiminpay.paymentagent.api.dto.AlipayBean;
import com.huiminpay.paymentagent.api.dto.PaymentResponseDTO;
import com.huiminpay.paymentagent.api.dto.TradeStatus;
import com.huiminpay.paymentagent.constant.AliCodeConstants;
import com.huiminpay.paymentagent.message.PayProducer;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

@org.apache.dubbo.config.annotation.Service
@Slf4j
public class PayChannelAgentServiceImpl implements PayChannelAgentService {

    final String CHARSET = "utf-8";

    @Autowired
    private PayProducer payProducer;


    /**
     * \* 调用支付宝手机WAP下单接口
     * \* @param aliConfigParam 支付渠道参数
     * \* @param alipayBean   请求支付参数
     * \* @return
     * \* @throws BusinessException
     */
    @Override
    public PaymentResponseDTO createPayOrderByAliWAP(AliConfigParam aliConfigParam, AlipayBean alipayBean) throws BusinessException {
        log.info("支付宝请求参数", alipayBean.toString());
        String gateway = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";//正式"https://openapi.alipay.com/gateway.do"

        String appId = aliConfigParam.getAppId();
        String rsaPrivateKey = aliConfigParam.getRsaPrivateKey();
        String alipayPublicKey = aliConfigParam.getAlipayPublicKey();
        String format = aliConfigParam.getFormat();
        String signtype = aliConfigParam.getSigntype();
        String notifyUrl = aliConfigParam.getNotifyUrl();
        String returnUrl = aliConfigParam.getReturnUrl();

        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(gateway.toString(), appId.toString(), rsaPrivateKey.toString(), format.toString(), CHARSET, alipayPublicKey.toString(), signtype.toString());

        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();            //创建API对应的request

        //将alipayBean的参数装配到AlipayTradeWapPayModel
        AlipayTradeWapPayModel model = getAlipayTradeWapPayModel(alipayBean);

        String jsonString = JSON.toJSONString(alipayBean);
        log.info("createPayOrderByAliWAP..alipayRequest:{}", jsonString);

        alipayRequest.setBizModel(model);
        alipayRequest.setNotifyUrl(notifyUrl);
        alipayRequest.setReturnUrl(returnUrl);

        String form = null; //调用SDK生成表单
        try {
            // 发送支付结果查询延迟消息
            PaymentResponseDTO<AliConfigParam> notice = new PaymentResponseDTO<>();
            notice.setOutTradeNo(alipayBean.getOutTradeNo());
            notice.setContent(aliConfigParam);
            notice.setMsg("ALIPAY_WAP");
            payProducer.payOrderNotice(notice);


            form = alipayClient.pageExecute(alipayRequest).getBody();
            log.info("支付宝H5支付响应Content:" + form);

        } catch (AlipayApiException e) {
            log.error("AlipayApiException:", e);
            throw new BusinessException(CommonErrorCode.E_400002);
        }

        PaymentResponseDTO responseDTO = new PaymentResponseDTO();
        responseDTO.setContent(form);
        return responseDTO;
    }


    /**
     * 装配参数到AlipayTradeWapPayModel中，并返回
     */
    private static AlipayTradeWapPayModel getAlipayTradeWapPayModel(AlipayBean alipayBean) {
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(alipayBean.getOutTradeNo());
        model.setTotalAmount(alipayBean.getTotalAmount());
        model.setSubject(alipayBean.getSubject());
        model.setProductCode(alipayBean.getProductCode());
        model.setBody(alipayBean.getBody());
        model.setTimeoutExpress(alipayBean.getExpireTime());
        model.setProductCode(alipayBean.getProductCode());
        return model;
    }

    @Override
    public PaymentResponseDTO queryPayOrderByAli(AliConfigParam aliConfigParam, String outTradeNo) {
        String gateway = aliConfigParam.getUrl();
        String appId = aliConfigParam.getAppId();
        String rsaPrivateKey = aliConfigParam.getRsaPrivateKey();
        String format = aliConfigParam.getFormat();
        String charest = aliConfigParam.getCharest();
        String alipayPublicKey = aliConfigParam.getAlipayPublicKey();
        String signtype = aliConfigParam.getSigntype();
        log.info("C扫B请求支付宝查询订单，参数：{}", JSON.toJSONString(aliConfigParam));

        DefaultAlipayClient alipayClient = new DefaultAlipayClient(gateway, appId, rsaPrivateKey, format, charest, alipayPublicKey, signtype);
        AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();
        AlipayTradePayModel alipayTradePayModel = new AlipayTradePayModel();
        alipayTradePayModel.setOutTradeNo(outTradeNo);
        alipayTradeQueryRequest.setBizModel(alipayTradePayModel);
        PaymentResponseDTO dto;
        try {
            AlipayTradeQueryResponse execute = alipayClient.execute(alipayTradeQueryRequest);
            if (AliCodeConstants.SUCCESSCODE.equals(execute.getCode())) {
                TradeStatus tradeStatus = covertAliTradeStatusTohuiminCode(execute.getTradeStatus());
                dto = PaymentResponseDTO.success(execute.getTradeNo(), execute.getOutTradeNo(), tradeStatus, execute.getMsg() + "" + execute.getSubMsg());
                log.info("‐‐‐‐查询支付宝H5支付结果" + JSON.toJSONString(dto));
                return dto;
            }
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        dto = PaymentResponseDTO.fail("查询支付宝支付结果异常", outTradeNo, TradeStatus.UNKNOWN);
        return dto;
    }


    /**
     * 将支付宝查询时订单状态trade_status 转换为 惠民订单状态
     *
     * @param aliTradeStatus 支付宝交易状态
     *                       WAIT_BUYER_PAY（交易创建，等待买家付款）
     *                       TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）
     *                       TRADE_SUCCESS（交易支付成功）
     *                       TRADE_FINISHED（交易结束，不可退款）
     * @return
     */
    private TradeStatus covertAliTradeStatusTohuiminCode(String aliTradeStatus) {

        switch (aliTradeStatus) {
            case AliCodeConstants.WAIT_BUYER_PAY:
                return TradeStatus.USERPAYING;
            case AliCodeConstants.TRADE_SUCCESS:
            case AliCodeConstants.TRADE_FINISHED:
                return TradeStatus.SUCCESS;
            default:
                return TradeStatus.FAILED;
        }
    }
}    